const WebSocket = require('ws')
const url = require('url')
const { v4: uuidv4 } = require('uuid')

// 增加WebRTC连接调试日志
const DEBUG_WEBRTC = true;

// 添加日志颜色
const LOG_COLORS = {
  GREEN: '\x1b[32m',
  YELLOW: '\x1b[33m',
  RED: '\x1b[31m',
  BLUE: '\x1b[34m',
  MAGENTA: '\x1b[35m',
  CYAN: '\x1b[36m',
  RESET: '\x1b[0m'
};

function initializeWebSocket(server) {
  // 创建 WebSocket 服务器，使用与 Express 相同的 HTTP server
  const wss = new WebSocket.Server({
    server,
    path: '/ws',  // 明确指定WebSocket路径
    // 添加 CORS 支持
    verifyClient: (info) => {
      console.log(`${LOG_COLORS.BLUE}WebSocket连接尝试，Origin: ${info.origin || '无'}, URL: ${info.req.url}${LOG_COLORS.RESET}`);

      // 放宽连接限制，允许更多连接
      return true;
    }
  })

  console.log(`${LOG_COLORS.GREEN}WebSocket服务器初始化完成${LOG_COLORS.RESET}`);
  console.log(`${LOG_COLORS.YELLOW}WebRTC调试模式: ${DEBUG_WEBRTC ? '开启' : '关闭'}${LOG_COLORS.RESET}`);

  // 用于存储客户端连接，格式为 { userId: ws }
  const clients = new Map()

  // --- 心跳机制 ---
  function heartbeat() {
    this.isAlive = true
  }

  const interval = setInterval(() => {
    wss.clients.forEach((ws) => {
      if (ws.isAlive === false) {
        for (const [userId, client] of clients.entries()) {
          if (client === ws) {
            console.log(`${LOG_COLORS.YELLOW}心跳检测：用户 "${userId}" 连接已断开。${LOG_COLORS.RESET}`)
            clients.delete(userId)
            broadcastOnlineUsers()
            break
          }
        }
        return ws.terminate()
      }
      ws.isAlive = false
      ws.ping()
    })
  }, 30000)

  wss.on('close', () => {
    clearInterval(interval)
  })

  // 广播函数
  function broadcast(data) {
    const message = JSON.stringify(data)
    for (const client of wss.clients) {
      if (client.readyState === WebSocket.OPEN) {
        client.send(message)
      }
    }
  }

  // 更新并广播在线用户列表
  function broadcastOnlineUsers() {
    const onlineUsers = Array.from(clients.keys())
    console.log(`${LOG_COLORS.CYAN}广播在线用户:${LOG_COLORS.RESET}`, onlineUsers)
    broadcast({
      type: 'userList',
      users: onlineUsers
    })
  }

  // 监听新的连接
  wss.on('connection', (ws, req) => {
    ws.isAlive = true
    ws.on('pong', heartbeat)

    const parameters = new url.URL(
      req.url,
      `${req.headers.origin || `http://${req.headers.host}`}`
    ).searchParams
    const userId = parameters.get('userId')

    if (!userId || clients.has(userId)) {
      console.log(`${LOG_COLORS.RED}连接失败：用户ID "${userId}" 无效或已存在。${LOG_COLORS.RESET}`)
      ws.close(1008, 'Invalid or duplicate userId')
      return
    }

    clients.set(userId, ws)
    console.log(`${LOG_COLORS.GREEN}用户 "${userId}" 已连接。当前在线人数: ${clients.size}${LOG_COLORS.RESET}`)
    ws.send(JSON.stringify({ type: 'welcome', message: `欢迎, ${userId}!` }))
    broadcastOnlineUsers()

    ws.on('close', () => {
      for (const [id, client] of clients.entries()) {
        if (client === ws) {
          console.log(
            `${LOG_COLORS.YELLOW}用户 "${id}" 已断开连接。当前在线人数: ${clients.size - 1}${LOG_COLORS.RESET}`
          )
          clients.delete(id)
          broadcastOnlineUsers()
          break
        }
      }
    })

    ws.on('message', (message) => {
      try {
        const parsedMessage = JSON.parse(message)

        if (parsedMessage.type === 'logout') {
          console.log(`${LOG_COLORS.YELLOW}用户 "${userId}" 主动退出。${LOG_COLORS.RESET}`)
          return
        }

        if (
          parsedMessage.type.startsWith('webrtc-') ||
          ['start-call', 'end-call', 'ice-timeout'].includes(parsedMessage.type)
        ) {
          const recipientWs = clients.get(parsedMessage.to)
          if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
            const signalingMessage = { ...parsedMessage, from: userId }
            recipientWs.send(JSON.stringify(signalingMessage))

            // 增强日志：显示不同类型信令的详细信息
            if (DEBUG_WEBRTC) {
              if (parsedMessage.type === 'start-call') {
                console.log(`${LOG_COLORS.BLUE}[WebRTC] ${userId} 向 ${parsedMessage.to} 发起通话请求${LOG_COLORS.RESET}`);
              } else if (parsedMessage.type === 'webrtc-answer') {
                console.log(`${LOG_COLORS.BLUE}[WebRTC] ${userId} 接受 ${parsedMessage.to} 的通话请求${LOG_COLORS.RESET}`);
              } else if (parsedMessage.type === 'end-call') {
                console.log(`${LOG_COLORS.BLUE}[WebRTC] ${userId} 结束与 ${parsedMessage.to} 的通话${LOG_COLORS.RESET}`);
              } else if (parsedMessage.type === 'webrtc-ice-candidate') {
                // 解析ICE候选者类型
                let candidateType = '未知';
                try {
                  const candidateStr = parsedMessage.candidate.candidate;
                  if (candidateStr.includes('typ host')) candidateType = 'host(本地)';
                  else if (candidateStr.includes('typ srflx')) candidateType = 'srflx(STUN)';
                  else if (candidateStr.includes('typ relay')) candidateType = 'relay(TURN)';

                  console.log(`${LOG_COLORS.MAGENTA}[ICE] ${userId} → ${parsedMessage.to} 发送ICE候选: ${candidateType}${LOG_COLORS.RESET}`);
                  if (candidateType === 'relay(TURN)') {
                    console.log(`${LOG_COLORS.GREEN}✓ 检测到TURN中继候选者，NAT穿透正常工作${LOG_COLORS.RESET}`);
                  }
                } catch (e) {
                  console.log(`${LOG_COLORS.MAGENTA}[ICE] ${userId} → ${parsedMessage.to} 发送ICE候选${LOG_COLORS.RESET}`);
                }
              } else if (parsedMessage.type === 'ice-timeout') {
                console.log(`${LOG_COLORS.RED}[ICE超时] ${userId} → ${parsedMessage.to} ICE连接超时: ${parsedMessage.message}${LOG_COLORS.RESET}`);
              } else {
                console.log(`${LOG_COLORS.BLUE}[WebRTC] ${userId} → ${parsedMessage.to} 信令类型: ${parsedMessage.type}${LOG_COLORS.RESET}`);
              }
            } else {
              console.log(
                `[Signaling] 转发消息 from ${userId} to ${parsedMessage.to}, type: ${parsedMessage.type}`
              )
            }
          } else {
            console.log(`${LOG_COLORS.RED}[Signaling] 无法转发消息，目标用户 ${parsedMessage.to} 不在线或连接已关闭${LOG_COLORS.RESET}`)
            // 通知发送者对方不在线
            const ws = clients.get(userId)
            if (ws && ws.readyState === WebSocket.OPEN) {
              ws.send(JSON.stringify({
                type: 'error',
                message: `用户 "${parsedMessage.to}" 不在线，无法建立视频通话。`
              }))
            }
          }
          return
        }

        const messageId = uuidv4()

        if (
          parsedMessage.type === 'privateMessage' &&
          parsedMessage.to &&
          parsedMessage.content
        ) {
          const recipientWs = clients.get(parsedMessage.to)
          if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
            // 使用客户端提供的ID（如果有），否则生成新ID
            const id = parsedMessage.id || messageId;
            const privateMessage = {
              id: id,
              type: 'privateMessage',
              from: userId,
              to: parsedMessage.to,
              content: parsedMessage.content,
              timestamp: new Date().toISOString()
            }
            // 只发送给接收者，不发回给发送者
            recipientWs.send(JSON.stringify(privateMessage))
            console.log(
              `消息从 "${userId}" 发送给 "${parsedMessage.to}": ${parsedMessage.content}`
            )
          } else {
            console.log(`发送失败：用户 "${parsedMessage.to}" 未找到或已离线。`)
            ws.send(
              JSON.stringify({
                type: 'error',
                message: `用户 "${parsedMessage.to}" 未找到或已离线。`
              })
            )
          }
        } else if (
          parsedMessage.type === 'imageMessage' &&
          parsedMessage.to &&
          parsedMessage.content
        ) {
          const recipientWs = clients.get(parsedMessage.to)
          if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
            // 使用客户端提供的ID（如果有），否则生成新ID
            const id = parsedMessage.id || messageId;
            const imageMessage = {
              id: id,
              type: 'imageMessage',
              from: userId,
              to: parsedMessage.to,
              content: parsedMessage.content,
              isFlash: !!parsedMessage.isFlash,
              timestamp: new Date().toISOString()
            }
            // 只发送给接收者，不发回给发送者
            recipientWs.send(JSON.stringify(imageMessage))
            console.log(
              `图片(闪图: ${imageMessage.isFlash}) 从 "${userId}" 发送给 "${parsedMessage.to}"`
            )
          } else {
            ws.send(
              JSON.stringify({
                type: 'error',
                message: `发送图片失败：用户 "${parsedMessage.to}" 未找到或已离线。`
              })
            )
          }
        } else if (
          parsedMessage.type === 'videoMessage' &&
          parsedMessage.to &&
          parsedMessage.content
        ) {
          const recipientWs = clients.get(parsedMessage.to)
          if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
            // 使用客户端提供的ID（如果有），否则生成新ID
            const id = parsedMessage.id || messageId;
            const videoMessage = {
              id: id,
              type: 'videoMessage',
              from: userId,
              to: parsedMessage.to,
              content: parsedMessage.content,
              isLargeVideo: !!parsedMessage.isLargeVideo, // 是否大视频（链接）
              videoMetadata: parsedMessage.videoMetadata || {}, // 视频元数据（宽、高、时长等）
              timestamp: new Date().toISOString()
            }
            // 只发送给接收者，不发回给发送者
            recipientWs.send(JSON.stringify(videoMessage))
            console.log(
              `视频(大视频: ${videoMessage.isLargeVideo}) 从 "${userId}" 发送给 "${parsedMessage.to}"`
            )
          } else {
            ws.send(
              JSON.stringify({
                type: 'error',
                message: `发送视频失败：用户 "${parsedMessage.to}" 未找到或已离线。`
              })
            )
          }
        } else {
          console.log(`收到来自 "${userId}" 的无效消息格式: ${message}`)
        }
      } catch (error) {
        console.error(`解析来自 "${userId}" 的消息失败:`, error)
        ws.send(
          JSON.stringify({
            type: 'error',
            message: `解析来自 "${userId}" 的消息失败: ${error.message}`
          })
        )
      }
    })
  })

  return wss; // 返回创建的WebSocket服务器实例
}

module.exports = { initializeWebSocket } 